package com.kun.portal.webframe.service;

import com.kun.portal.webframe.dao.AppointmentDao;
import com.kun.portal.webframe.dao.EquipmentDao;
import com.kun.portal.webframe.dao.FlightInfoDao;
import com.kun.portal.webframe.dao.FlightPlaneDao;
import com.kun.portal.webframe.po.*;
import com.kun.portal.webframe.util.PageImpl;
import com.kun.portal.webframe.util.Status;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.TemporalType;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Created by Administrator on 2018/5/10.
 */
@Service
public class FlightPlaneService {
    @Autowired
    private FlightPlaneDao flightPlaneDao;
    @Autowired
    private AppointmentDao appointmentDao;
    @Autowired
    private EntityManager entityManager;

    @Transactional
    public FlightPlanePo save(FlightPlanePo flightPlanePo){
        if(StringUtils.isNotBlank(flightPlanePo.getPlaneId())){
            List <AppointmentPo> list= appointmentDao.findAll(new Specification<AppointmentPo>() {
                @Override
                public Predicate toPredicate(Root<AppointmentPo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                    return criteriaBuilder.equal(root.get("flightPlane" ),flightPlanePo);
                }
            });
            for(AppointmentPo app :list){
                app.setAppoDate(flightPlanePo.getExpectDate());
            }
            appointmentDao.save(list);

        }
        return flightPlaneDao.save(flightPlanePo);
    }
    public List<FlightPlanePo> batchSave(List<FlightPlanePo> flightPlanePos){
        return flightPlaneDao.save (flightPlanePos);
    }
    public Page<FlightPlanePo>  query(Pageable pageable, Date startDate, Date endDate, String flightInfoId){
        Specification query=  new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
                Predicate predicate= cb.notEqual(root.get("planeStatus"),"删除");
                if(startDate!=null){
                    predicate =cb.greaterThanOrEqualTo(root.get("expectDate"),startDate) ;
                }
                if(endDate!=null){
                    if(predicate!=null){
                        predicate =cb.and(predicate,cb.lessThanOrEqualTo(root.get("expectDate"),endDate)) ;
                    }else{
                        predicate =cb.lessThanOrEqualTo(root.get("expectDate"),endDate) ;
                    }

                }
                if(StringUtils.isNoneBlank(flightInfoId)){
                    if(predicate!=null){
                        FlightInfoPo flightInfoPo =  new FlightInfoPo();
                        flightInfoPo.setFlightInfoId(flightInfoId);
                        predicate =cb.and(predicate,cb.equal(root.get("flightInfo"),flightInfoPo)) ;
                    }else{
                        FlightInfoPo flightInfoPo =  new FlightInfoPo();
                        flightInfoPo.setFlightInfoId(flightInfoId);
                        predicate = cb.equal(root.get("flightInfo"),flightInfoPo);
                    }

                }
                return predicate;
            }
        };

        return flightPlaneDao.findAll(query,pageable);
    }
    public Page<FlightPlanePo> queryInterimPlane(Pageable pageable, String planeProperty, Date exceptDate, Date estimatedTime,String importOrExport){


        Specification query = new Specification<FlightPlanePo>() {
            @Override
            public Predicate toPredicate(Root<FlightPlanePo> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> pre= new ArrayList<>();
                if(null != estimatedTime){
                    pre.add(cb.equal(root.get("estimatedTime"), estimatedTime));
                }
                if(null != exceptDate){
                    pre.add(cb.equal(root.get("estimatedTime"), estimatedTime));
                }
                if(StringUtils.isNotBlank(importOrExport)){
                    pre.add(cb.like(root.get("importOrExport"), "%"+importOrExport+"%"));
                }
                if(StringUtils.isNotBlank(planeProperty)){
                    pre.add(cb.like(root.get("planeProperty"), "%"+planeProperty+"%"));
                }

                Predicate predicate = cb.and(pre.toArray(new Predicate[pre.size()]));
                return predicate;
            }
        };
        return flightPlaneDao.findAll(query,pageable);


    }



    public List<FlightPlanePo> findFlightDynamicPlaneNoPage( Boolean all ,Boolean export,Boolean isImport,
                                                             Boolean normal,
                                                             Boolean abnormal,
                                                             Boolean overtime,   String flightNum,  String order){

        String sql = "select p from FlightPlanePo p left join fetch p.flightInfo f where 1=1 ";
        sql+= " and p.estimatedTime between :exceptDateS and :exceptDateE ";
        String adds = "";
        boolean head = false;
        boolean addOr =false;
        boolean end=false;
        if(export!=null&&export ){
            adds+= " p.importOrExport= '出港' or p.importOrExport= '中转联程'";
            addOr=true;
            head=true;
        }
        if(isImport!=null&&isImport ){
            if(addOr){
                adds+=" or ";
            }
            adds+= " p.importOrExport= '进港' or p.importOrExport= '中转联程'";
            head=true;

        }
        String s= "";
        addOr =false;
        if(abnormal!=null&&abnormal ){
            addOr=true;
            end = true;
            s+= " p.normalAbnormality= '异常' ";
        }
        if(normal!=null&&normal ){
            if(addOr){
                s+=" or ";
            }
            addOr=true;
            end = true;
            s+= " p.normalAbnormality= '正常' ";
        }
        if(overtime!=null&&overtime ){
            if(addOr){
                s+=" or ";
            }
            addOr=true;
            end = true;
            s+= " p.normalAbnormality= '加班' ";
        }

        if(head&&end){
            sql +="and ("+adds+") and ("+s+")";
        }else{
            if(head||end){
                sql+="and ("+(adds+s)+")";
            }

        }

        if(StringUtils.isNotBlank(flightNum)){
            sql+= " and  f.flightNum like '%"+flightNum+"%'";
        }
        Query query = entityManager.createQuery(sql);
        query.setParameter("exceptDateS",new Date(),TemporalType.DATE);
        query.setParameter("exceptDateE",new Date(),TemporalType.DATE);
        return query.getResultList();

    };
    public List<FlightPlanePo> queryInterimPlaneNoPage(String  order,String flightInfoId , String planeProperty, Date exceptDateS, Date exceptDateE, Date estimatedTimeS, Date estimatedTimeE, String importOrExport){

        String sql = "select p from FlightPlanePo p left join fetch p.flightInfo f where not (p.planeRunStatus = "+ Status.COMPLETED +" )";
        if(StringUtils.isNotBlank(flightInfoId)){
            sql+= "  and f.flightInfoId = '"+flightInfoId+"' ";
        }
        if(StringUtils.isNotBlank(planeProperty)){
            sql += " and p.planeProperty = '"+planeProperty+"' ";
        }
        if(StringUtils.isNotBlank(importOrExport)){
            sql += " and p.importOrExport ='"+importOrExport+"'";
        }
        if(exceptDateS!=null&&exceptDateE!=null){
            sql+= " and p.expectDate between :exceptDateS and :exceptDateE";
        }

        if(estimatedTimeS!=null &&estimatedTimeE!=null){
            sql+= " and p.estimatedTime between :estimatedTimeS and :estimatedTimeE";
        }
//        if(estimatedTimeS==null&&estimatedTimeE==null){
//            sql+= " and p.estimatedTime >= :estimatedTime";
//        }
        if(StringUtils.isNotBlank(order)){
            sql +=" order by p."+order;
        }
        Query query = entityManager.createQuery(sql);
        if(exceptDateS!=null &exceptDateE!=null){
            query.setParameter("exceptDateS",exceptDateS,TemporalType.DATE);
            query.setParameter("exceptDateE",exceptDateE,TemporalType.DATE);
        }
        if(estimatedTimeS!=null &estimatedTimeE!=null){
            query.setParameter("estimatedTimeS",estimatedTimeS,TemporalType.DATE);
            query.setParameter("estimatedTimeE",estimatedTimeE,TemporalType.DATE);
        }
//        if(estimatedTimeS==null&&estimatedTimeE==null){
//            query.setParameter("estimatedTime",new Date(),TemporalType.DATE);
//        }

        return query.getResultList();

    };


    public List<FlightPlanePo> queryAppointmentPlaneNoPage(String  order,String flightInfoId , String planeProperty, Date exceptDateS, Date exceptDateE, Date estimatedTimeS, Date estimatedTimeE, String importOrExport){

        String sql = "select p from FlightPlanePo p left join fetch p.flightInfo f where p.planeRunStatus = "+ Status.PUBLISHED +" ";
        if(StringUtils.isNotBlank(flightInfoId)){
            sql+= "  and f.flightInfoId = '"+flightInfoId+"' ";
        }
        if(StringUtils.isNotBlank(planeProperty)){
            sql += " and p.planeProperty = '"+planeProperty+"' ";
        }
        if(StringUtils.isNotBlank(importOrExport)){
            sql += " and p.importOrExport ='"+importOrExport+"'";
        }
        if(exceptDateS!=null&&exceptDateE!=null){
            sql+= " and p.expectDate between :exceptDateS and :exceptDateE";
        }

        if(estimatedTimeS!=null &&estimatedTimeE!=null){
            sql+= " and p.estimatedTime between :estimatedTimeS and :estimatedTimeE";
        }
//        if(estimatedTimeS==null&&estimatedTimeE==null){
//            sql+= " and p.estimatedTime >= :estimatedTime";
//        }
        if(StringUtils.isNotBlank(order)){
            sql +=" order by p."+order;
        }
        Query query = entityManager.createQuery(sql);
        if(exceptDateS!=null &exceptDateE!=null){
            query.setParameter("exceptDateS",exceptDateS,TemporalType.DATE);
            query.setParameter("exceptDateE",exceptDateE,TemporalType.DATE);
        }
        if(estimatedTimeS!=null &estimatedTimeE!=null){
            query.setParameter("estimatedTimeS",estimatedTimeS,TemporalType.DATE);
            query.setParameter("estimatedTimeE",estimatedTimeE,TemporalType.DATE);
        }
//        if(estimatedTimeS==null&&estimatedTimeE==null){
//            query.setParameter("estimatedTime",new Date(),TemporalType.DATE);
//        }

        return query.getResultList();

    };
    public List<FlightPlanePo> queryNextPlane(String  order,String flightInfoId , Date estimatedTime, String importOrExport){

        String sql = "select p from FlightPlanePo p left join fetch p.flightInfo f where 1=1 ";
        if(StringUtils.isNotBlank(flightInfoId)){
            sql+= " and f.flightInfoId = '"+flightInfoId+"' ";
        }
        if(StringUtils.isNotBlank(importOrExport)){
            sql += " and p.importOrExport ='"+importOrExport+"'";
        }

        if(estimatedTime!=null){
            sql += " and p.estimatedTime = :estimatedTime";
        }
        if(StringUtils.isNotBlank(order)){
            sql +=" order by p."+order;
        }
        Query query = entityManager.createQuery(sql);
        if(estimatedTime!=null){
            query.setParameter("estimatedTime",estimatedTime,TemporalType.DATE);
        }
        return query.getResultList();

    };

    public List<FlightPlanePo> queryTodayPlaneWidthNode(String  order,String flightInfoId , Date estimatedTime, String importOrExport){

        String sql = "select distinct p from FlightPlanePo p left join fetch p.flightInfo f left join  fetch  p.courseNodePos c left join fetch c.dataEntryClerk where p.planeRunStatus="+Status.PUBLISHED+" ";
        if(StringUtils.isNotBlank(flightInfoId)){
            sql+= " and f.flightInfoId = '"+flightInfoId+"' ";
        }
        if(StringUtils.isNotBlank(importOrExport)){
            sql += " and p.importOrExport ='"+importOrExport+"'";
        }


        sql += " and p.estimatedTime = :estimatedTime";

        if(StringUtils.isNotBlank(order)){
            sql +=" order by p."+order;
        }
        Query query = entityManager.createQuery(sql);
        if(estimatedTime!=null){
            query.setParameter("estimatedTime",estimatedTime,TemporalType.DATE);
        }else{
            query.setParameter("estimatedTime",new Date(),TemporalType.DATE);
        }
        return query.getResultList();

    };

    public List<FlightPlanePo> queryNow(String flightNum){
        Specification query=  new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
                Calendar calendar = Calendar.getInstance();
                Date startDate=new Date();
                calendar.setTime(new Date());
                calendar.add(Calendar.HOUR,24);
                Date endDate = calendar.getTime();

                calendar.setTime(new Date());
                calendar.add(Calendar.HOUR,-10);
                Date imStartTime=  calendar.getTime();
                calendar.setTime(new Date());
                calendar.add(Calendar.HOUR,2);
                Date imEndDate = calendar.getTime();
//
//                Predicate e= cb.greaterThanOrEqualTo(root.get("takeOffTime"),startDate);
//                Predicate f= cb.lessThanOrEqualTo(root.get("takeOffTime"),endDate);

                Predicate g= cb.between(root.get("takeOffTime"),startDate,endDate);
//                Predicate g = cb.equal(root.get("importOrExport"),"出港");

//
//                Predicate a= cb.greaterThanOrEqualTo(root.get("arriveTime"),imStartTime);
//                Predicate b=cb.lessThanOrEqualTo(root.get("arriveTime"),imEndDate);
                Predicate h=cb.between(root.get("arriveTime"),imStartTime,imEndDate);
//                Predicate c = cb.equal(root.get("importOrExport"),"进港");
                return cb.or(g,h);
            }
        };
        return flightPlaneDao.findAll(query);
    }
    public FlightPlanePo findOneById(String planeId){
        Query query =  entityManager.createQuery("select  p from FlightPlanePo p left join fetch  p.gpConfigPo left join fetch  p.flightInfo f left join fetch  f.gpConfigPo  gpc left join fetch  gpc.currentFlight  where p.planeId = '"+planeId+"'");
        return (FlightPlanePo) query.getSingleResult();
    }
    public List<FlightPlanePo> findFlightDynamicPlaneToday(Date estimatedTime,String flightNum,String importOrExport,String order){
        String sql = "select p from FlightPlanePo p   left join fetch p.gpConfigPo left join fetch p.flightInfo f LEFT JOIN FETCH f.gpConfigPo where 1=1 and p.planeRunStatus="+Status.PUBLISHED+" and p.planeRunStatus <"+Status.COMPLETED;
        if(StringUtils.isNotBlank(flightNum)){
            sql+= " and  f.flightNum like '%"+flightNum+"%'";
        }
        if(StringUtils.isNotBlank(importOrExport)){
            sql += " and p.importOrExport ='"+importOrExport+"'";
        }
        if(estimatedTime!=null){
            sql += " and p.estimatedTime = :estimatedTime";
        }

        if(StringUtils.isNotBlank(order)){
            sql +=" order by p."+order;
        }
        Query query = entityManager.createQuery(sql);
        if(estimatedTime!=null){
            query.setParameter("estimatedTime",estimatedTime,TemporalType.DATE);
        }
        return query.getResultList();

    }

}
